package com.yeskery.nut.extend.mcp.server;

import com.yeskery.nut.bean.ApplicationContext;
import com.yeskery.nut.bean.FactoryBeanRegister;
import com.yeskery.nut.extend.mcp.annotation.McpPrompt;
import com.yeskery.nut.extend.mcp.annotation.McpPromptProperty;
import com.yeskery.nut.extend.mcp.core.Prompt;
import com.yeskery.nut.extend.mcp.core.schema.PromptSchema;
import com.yeskery.nut.util.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

/**
 * Mcp提示bean后置处理器
 * @author sprout
 * 2025-04-18 11:22
 */
public class McpPromptBeanPostProcessor extends BaseMcpBeanPostProcessor {

    /**
     * 构建Mcp工具bean后置处理器
     * @param mcpServerCapability mcp服务能力
     */
    public McpPromptBeanPostProcessor(McpServerCapability mcpServerCapability) {
        super(mcpServerCapability);
    }

    @Override
    protected Class<? extends Annotation> getMethodTargetAnnotation() {
        return McpPrompt.class;
    }

    @Override
    protected void doProcess(Object bean, Class<?> beanClass, Method method, ApplicationContext applicationContext, FactoryBeanRegister factoryBeanRegister) {
        List<PromptSchema.PromptArgument> arguments = new ArrayList<>(method.getParameters().length);
        for (Parameter parameter : method.getParameters()) {
            Class<?> parameterType = parameter.getType();
            if (!isBasicType(parameterType)) {
                throw new McpServerException("Parameter Only Support Basic Type, Current Type[" + parameterType + "] Not Support.");
            }
            McpPromptProperty mcpPromptProperty = parameter.getAnnotation(McpPromptProperty.class);
            String name = parameter.getName();
            if (mcpPromptProperty != null) {
                if (!StringUtils.isBlank(mcpPromptProperty.value())) {
                    name = mcpPromptProperty.value();
                }
            }
            PromptSchema.PromptArgument promptArgument = new PromptSchema.PromptArgument();
            promptArgument.setName(name);
            promptArgument.setDescription(mcpPromptProperty == null ? "" : mcpPromptProperty.description());
            promptArgument.setRequired(mcpPromptProperty == null || mcpPromptProperty.required());
            arguments.add(promptArgument);
        }
        Prompt prompt = createPrompt(method);
        prompt.getPrompt().setArguments(arguments);
        McpPromptMetadata promptMetadata = new McpPromptMetadata();
        promptMetadata.setBean(bean);
        promptMetadata.setMethod(method);
        promptMetadata.setPrompt(prompt);
        getMcpServerCapability().addPromptMetadata(promptMetadata);
    }

    /**
     * 创建资源
     * @param method 资源对象
     * @return 资源对象
     */
    private Prompt createPrompt(Method method) {
        McpPrompt mcpPrompt = method.getAnnotation(McpPrompt.class);
        PromptSchema.Prompt schemaPrompt = getSchemaPrompt(mcpPrompt);
        Prompt prompt = new Prompt();
        prompt.setPrompt(schemaPrompt);
        return prompt;
    }

    /**
     * 获取提示对象
     * @param mcpPrompt Mcp提示注解
     * @return 提示对象
     */
    private PromptSchema.Prompt getSchemaPrompt(McpPrompt mcpPrompt) {
        PromptSchema.Prompt prompt = new PromptSchema.Prompt();
        prompt.setName(mcpPrompt.name());
        prompt.setDescription(mcpPrompt.description());
        return prompt;
    }
}
